
import Icon from '@ant-design/icons';
import React from "react";
import { Button, Divider, Flex, Form, type FormItemProps, message, Space, Tooltip } from "@/components/base";
import { useElementResize, useItemWidth, useFormMonitorValues } from "@/utils/hooks";
import styles from './index.module.less';
import I001 from "./icons/I001.svg?react";
import I002 from "./icons/I002.svg?react";

export interface IFilterItems extends FormItemProps {
    /** 分组id */
    group?: React.Key;
}

export interface IGroupConfig {
    /** 分组名称 */
    name: string;

    /** 分组id */
    id: React.Key;

    /** 分组表示 */
    key: string;
}

export interface IPageFilterProps<S> {

    /** 文本宽度 */
    formFlex?: number;

    /** 筛选条件 */
    items?: IFilterItems[];

    /** 点击了搜索条件 */
    onSearch?: (e: S) => void;

    /** 搜索提交变化 */
    onChange?: (e: S) => void;

    /** 筛选数据 */
    searchData?: S;

    /** 默认是否折叠 */
    defaultCollapsed?: boolean;

    /** 最小宽度 */
    minWidth?: number;

    /** 分组配置 */
    groupConfig?: Map<React.Key, IGroupConfig>;

    style?: React.CSSProperties
}

/** 页面筛选器 */
export function PageFilter<S = any>(props: IPageFilterProps<S>) {

    const {
        style,
        formFlex = 70,
        items = [],
        defaultCollapsed = true,
        minWidth = 300,
        groupConfig = new Map<React.Key, IGroupConfig>(),
    } = props;

    const [opacity, setOpacity] = React.useState<number>(0);
    const [form] = Form.useForm<S>();
    const { onRef, width } = useElementResize<HTMLDivElement>();
    const { itemWidth, rowQuantity } = useItemWidth(width, minWidth);
    const [collapsed, setCollapsed] = React.useState<boolean>(defaultCollapsed); // 是否折叠

    /** 表单变化 */
    const onValuesChange = React.useCallback((allValues: any) => {
        props.onChange?.(allValues);
    }, [props]);

    const { values, onFieldsChange, setValues } = useFormMonitorValues({ onChange: onValuesChange });

    /** 查询 */
    const onSearch = React.useCallback(async () => {
        try {
            await form.validateFields();
            props.onSearch?.(values);
        } catch (error: any) {
            const content = error.errorFields[0].errors[0];
            message.error({ content, key: content });
        }
    }, [form, props, values]);

    /** 重置 */
    const onReset = React.useCallback(async () => {
        form.resetFields();
        const v = form.getFieldsValue();
        props.onChange?.(v);
        setValues(v);
    }, [form, props, setValues]);

    /** 显示的搜索项目(未分组) */
    const showItems = React.useMemo(() => {
        return collapsed ? items.filter(filterGroup()).slice(0, rowQuantity - 1) : items.filter(filterGroup());
    }, [collapsed, items, rowQuantity]);

    /** 分组搜索项目 */
    const groupForm = React.useMemo(() => {
        return Array.from(groupConfig.values()).map(group => {
            const list = items.filter(filterGroup(group))
            if (list.length <= 0) return <></>;
            return (
                <>
                    <div style={{ width: '100%', display: collapsed ? 'none' : undefined }} >
                        <Divider orientation="left">{group.name}</Divider>
                    </div>
                    {list.map((item, index) => {
                        if (collapsed) return <></>;
                        return (
                            <Form.Item
                                // hidden={collapsed}
                                key={`H${index}`}
                                {...item}
                                name={[group.key, item.name]}
                                style={{ width: itemWidth - 10 }}
                                label={item.label && <FormItemLabel label={item.label} />}
                            />
                        )
                    })}
                </>
            )
        });
    }, [groupConfig, items, itemWidth, collapsed]);

    /** 操作按钮 */
    const operating = React.useMemo(() => {
        if (items.length <= 0) return <></>;

        const width = groupConfig.size > 0
            ? collapsed ? (rowQuantity - Math.floor(showItems.length % rowQuantity)) * itemWidth : '100%'
            : (rowQuantity - Math.floor(showItems.length % rowQuantity)) * itemWidth

        return (
            <div className={styles.operating} style={{ width }}>
                <Space>
                    <Button onClick={onSearch}>查询</Button>
                    <Button onClick={onReset} >重置</Button>
                    {
                        items.length > rowQuantity - 1 &&
                        <Button
                            type='link'
                            onClick={() => { setCollapsed(e => !e) }}
                        >
                            {collapsed ? '展开' : '收起'}
                            <Icon component={collapsed ? I001 : I002} />
                        </Button>
                    }
                </Space>
            </div>
        )
    }, [items.length, groupConfig.size, collapsed, rowQuantity, showItems.length, itemWidth, onSearch, onReset]);

    React.useEffect(() => {
        if (props.searchData) { 
            form.resetFields();
            form.setFieldsValue(props.searchData as any);
        } else {
            form.resetFields();
        }
    }, [props.searchData, form]);

    // 初始化先隐藏表单
    React.useEffect(() => {
        setTimeout(() => {
            setOpacity(1);
        }, 200);
    }, [])

    if (items.length <= 0) return <></>;
    
    return (
        <div ref={onRef} className={styles.pageFilter} style={{...style}}>
            <Form<S>
                form={form}
                style={{ opacity }}
                labelCol={{ flex: `${formFlex}px` }}
                labelAlign="right"
                onFieldsChange={onFieldsChange}
                onKeyDown={e => {
                    if (e.key === 'Enter')
                        onSearch();
                }}
            >
                <Flex justify='flex-start' align='flex-start' wrap gap={10}>
                    {showItems.map((item, index) => {
                        return (
                            <Form.Item
                                key={index}
                                {...item}
                                style={{ width: itemWidth - 10 }}
                                label={item.label && <FormItemLabel label={item.label} />}
                            />
                        );
                    })}
                    {groupForm}
                    {operating}
                </Flex>
            </Form>
        </div>
    );
}

/** 表单标题 */
const FormItemLabel = (props: { label?: React.ReactNode }) => {
    return (
        <Tooltip title={props.label}>
            <div className={styles.sourceFormItemTitle} >{props.label}</div>
        </Tooltip >
    )
}

/** 筛选制定分组 */
function filterGroup(groupConfig?: IGroupConfig) {
    return (filter: IFilterItems) => {
        if (groupConfig) {
            return groupConfig.id === filter.group;
        } else {
            return !filter.group
        }
    }
}